//
//  IWHWebview.m
//  YiYuanGou
//
//  Created by zhangtongle on 2017/5/5.
//  Copyright © 2017年 同乐1234521. All rights reserved.
//

#import "IWHWebview.h"
#import "WeakScriptMessageDelegate.h"
#import "ILGEncrypt.h"
#import "ILGLocalData.h"

static NSString* const WXAppSystemInfo = @"IWH.appGetSystemInfo";
static NSString* const WXApplicationInfo = @"IWH.appGetAppInfo";


@interface IWHWebview () <WKScriptMessageHandler, WKNavigationDelegate, WKUIDelegate, UIWebViewDelegate>

@property (nonatomic, strong) UIView *webView;

@property (nonatomic, strong) JSContext *jsContent;

@property (strong, nonatomic) NSDictionary *shareDic;

@property (assign, nonatomic) CGFloat sysVer;

@property (nonatomic, strong) NSArray *jsMethodHandleArr;

@property (strong, nonatomic) UIProgressView *progressView;
@property (assign, nonatomic) BOOL isShowProgress;

@end


@implementation IWHWebview

+ (IWHWebview *)IWHWebview:(CGRect)frame {
    IWHWebview *webContainer = [[NSBundle mainBundle] loadNibNamed:@"IWHWebview" owner:nil options:nil].firstObject;
    [webContainer setFrame:frame];
    
    webContainer.sysVer = [UIDevice currentDevice].systemVersion.floatValue;
    if (webContainer.sysVer >= 8.0) {
        WKWebView *wkWebView = [[WKWebView alloc] initWithFrame:webContainer.bounds];
        webContainer.webView = wkWebView;
        wkWebView.UIDelegate = webContainer;
//        [webContainer enableNavigationProgress];

        [webContainer p_addScriptMessageHandlers];
    } else {
        UIWebView *webView = [[UIWebView alloc] initWithFrame:frame];
        webContainer.webView = webView;
        
        webView.delegate = webContainer;
        webView.scrollView.bounces = NO;
        webView.scrollView.showsVerticalScrollIndicator = NO;
        webView.delegate = webContainer;
        
        [webContainer p_setDelegate];
    }
    
    [webContainer addSubview:webContainer.webView];

    return webContainer;
}

- (NSArray *)jsMethodHandleArr {
    if (!_jsMethodHandleArr) {
        _jsMethodHandleArr = @[@"setPageInfo", @"openWebView", @"closeWebView", @"getDeviceInfo", @"getAppInfo", @"messageSomeone", @"getToken"];
    }
    return _jsMethodHandleArr;
}

- (UIProgressView *)progressView
{
    if (!_progressView)
    {
        UIProgressView *progressView = [[UIProgressView alloc] initWithFrame:CGRectMake(0, 0, self.frame.size.width, 1)];
        progressView.tintColor = [UIColor blueColor];
        progressView.trackTintColor = [UIColor grayColor];
        [self addSubview:progressView];
        self.progressView = progressView;
    }
    return _progressView;
}

#pragma mark 计算wkWebView进度条
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
{
    if (object == (WKWebView *)self.webView && [keyPath isEqualToString:@"estimatedProgress"])
    {
        CGFloat newprogress = [[change objectForKey:NSKeyValueChangeNewKey] doubleValue];
        if (newprogress == 1)
        {
            self.progressView.hidden = YES;
            [self.progressView setProgress:0 animated:NO];
        }
        else
        {
            self.progressView.hidden = NO;
            [self.progressView setProgress:newprogress animated:YES];
        }
    }
}

- (void)loadRequest:(NSString *)urlStr {    
    NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:urlStr] cachePolicy:NSURLRequestReloadIgnoringLocalCacheData timeoutInterval:10];
    if (self.sysVer >= 8.0) {
        [(WKWebView *)self.webView loadRequest:request];

    } else {
        [(UIWebView *)self.webView loadRequest:request];
    }
}

- (void)navHidden:(BOOL)hidden {
    CGFloat screenHeight = [UIScreen mainScreen].bounds.size.height;
    CGRect webFrame = self.webView.frame;

    if (hidden) {
        self.navHeight.constant = 0;
        [self layoutIfNeeded];

//        webFrame.origin.y = 20;
//        webFrame.size.height = self.frame.size.height - 20;
        self.webView.frame = webFrame;

    } else {
        self.navHeight.constant = 44;
        [self layoutIfNeeded];

        webFrame.origin.y = 44;
        webFrame.size.height = screenHeight - 44;
        self.webView.frame = webFrame;
    }
    
    if (self.isShowProgress) {
        [self layoutProgress:hidden];

    }
}

- (void)layoutProgress:(BOOL)isNavHidden {
    CGRect newFrame = self.progressView.frame;
    
    if (isNavHidden) {
        newFrame.origin.y = 0;
        
    } else {
        newFrame.origin.y = 63;
    }
    
    self.progressView.frame = newFrame;
}

- (void)setMainWebView {
    _isMainWebView = YES;
}

- (void)enableNavigationProgress {
    self.isShowProgress = YES;
    
    [(WKWebView *)self.webView addObserver:self forKeyPath:@"estimatedProgress" options:NSKeyValueObservingOptionNew context:nil];
}

- (void)dealloc {
    if (self.sysVer >= 8.0) {
        [self p_removeScriptMessageHandlers];
        
        if (self.isShowProgress) {
            [(WKWebView *)self.webView removeObserver:self forKeyPath:@"estimatedProgress"];
        }
    } else {
        
    }
}


#pragma mark - delegate
#pragma mark WKScriptMessageHandler

- (void)userContentController:(WKUserContentController *)userContentController didReceiveScriptMessage:(WKScriptMessage *)message {
    NSString *methodName = message.name;
    NSString *mathodPara = message.body;

    if ([self respondsToSelector:NSSelectorFromString(methodName)]) {
        [self performSelector:NSSelectorFromString(methodName) withObject:mathodPara afterDelay:0];

    } else if ([self respondsToSelector:NSSelectorFromString([NSString stringWithFormat:@"%@:", methodName])]) {
        [self performSelector:NSSelectorFromString([NSString stringWithFormat:@"%@:", methodName]) withObject:mathodPara afterDelay:0];

    } else {
        NSLog(@"WebView call 未注册方法:%@", methodName);

    }
}

#pragma mark WKUIDelegate

- (void)webView:(WKWebView *)webView runJavaScriptAlertPanelWithMessage:(NSString *)message initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(void))completionHandler{
    completionHandler();
    NSLog(@"IWHWebView:%@", ((WKWebView *)self.webView).URL.absoluteString);
    // 由于多次弹出alertViewController，会引起崩溃问题，所以暂时换成UIAlertView
    //    UIAlertController *alertController = [UIAlertController alertControllerWithTitle:@"提示" message:message?:@"" preferredStyle:UIAlertControllerStyleAlert];
    //    [alertController addAction:([UIAlertAction actionWithTitle:@"确认" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
    //        if (completionHandler) {
    //            completionHandler();
    //
    //        }
    //    }])];
    
    [[[UIAlertView alloc] initWithTitle:@"提示" message:message?message:@""  delegate:nil cancelButtonTitle:@"我知道了" otherButtonTitles:nil, nil] show];
    
    if ([self.iwhDelegate respondsToSelector:@selector(IWHShowAlertView:animated:)]) {
        //        [self.iwhDelegate IWHShowAlertView:alertController animated:YES];
    }
}

- (void)webView:(WKWebView *)webView runJavaScriptConfirmPanelWithMessage:(NSString *)message initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(BOOL))completionHandler{
    //    DLOG(@"msg = %@ frmae = %@",message,frame);
    UIAlertController *alertController = [UIAlertController alertControllerWithTitle:@"提示" message:message?:@"" preferredStyle:UIAlertControllerStyleAlert];
    [alertController addAction:([UIAlertAction actionWithTitle:@"取消" style:UIAlertActionStyleCancel handler:^(UIAlertAction * _Nonnull action) {
        completionHandler(NO);
    }])];
    [alertController addAction:([UIAlertAction actionWithTitle:@"确认" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
        completionHandler(YES);
    }])];
    
    if ([self.iwhDelegate respondsToSelector:@selector(IWHShowAlertView:animated:)]) {
        [self.iwhDelegate IWHShowAlertView:alertController animated:YES];
    }
}

- (void)webView:(WKWebView *)webView runJavaScriptTextInputPanelWithPrompt:(NSString *)prompt defaultText:(NSString *)defaultText initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(NSString * _Nullable))completionHandler{
    UIAlertController *alertController = [UIAlertController alertControllerWithTitle:prompt message:@"" preferredStyle:UIAlertControllerStyleAlert];
    [alertController addTextFieldWithConfigurationHandler:^(UITextField * _Nonnull textField) {
        textField.text = defaultText;
    }];
    [alertController addAction:([UIAlertAction actionWithTitle:@"完成" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
        completionHandler(alertController.textFields[0].text?:@"");
    }])];
    
    
    if ([self.iwhDelegate respondsToSelector:@selector(IWHShowAlertView:animated:)]) {
        [self.iwhDelegate IWHShowAlertView:alertController animated:YES];
    }
}

#pragma mark UIWebViewDelegate

- (void)webViewDidFinishLoad:(UIWebView *)webView {
    if (!webView.isLoading) {
        [self p_setDelegate];
    }
}

#pragma mark JSObjectDelegate

- (void)setPageInfo:(NSString *)jsonStr {
    [self navHidden:NO];
    
    NSDictionary *pageDic = [ILGEncrypt dictionaryWithJsonString:jsonStr];
    
    self.navTitleL.text = pageDic[@"title"];
    
    NSString *leftTitle = pageDic[@"leftBtnTitle"];
    if (leftTitle.length) {
        [self.navBackBtn setBackgroundImage:nil forState:UIControlStateNormal];
        [self.navBackBtn setTitle:leftTitle forState:UIControlStateNormal];
    } else {
        int backBtnShowStatu = [pageDic[@"backButton"] intValue];
        if (backBtnShowStatu == 1) {
            self.navBackBtn.hidden = NO;
        } else {
            self.navBackBtn.hidden = YES;
        }
    }
    
    NSString *rightTitle = pageDic[@"rightBtnTitle"];
    if (rightTitle.length) {
        [self.navShareBtn setBackgroundImage:nil forState:UIControlStateNormal];
        [self.navShareBtn setTitle:rightTitle forState:UIControlStateNormal];
    }
}

- (void)openWebView:(NSString *)jsonStr {
    NSDictionary *urlDic = [ILGEncrypt dictionaryWithJsonString:jsonStr];
    
    NSLog(@"openUrl: urlInfo=%@", urlDic);
    
    if ([urlDic[@"target"] isEqualToString:@"_blank"]) {
//        CGRect frame = self.frame;
//        if (frame.size.height == [UIScreen mainScreen].bounds.size.height) {
//            frame.size.height -= 64;
//            frame.origin.y = 64;
//        }
//        IWHWebview *webContainer = [IWHWebview IWHWebview:frame];
//        [webContainer navHidden:YES];
//        [webContainer setFrame:frame];
//        
//        [webContainer loadRequest:urlDic[@"url"]];
//        webContainer.iwhDelegate = self.iwhDelegate;
//        [self.superview addSubview:webContainer];
        if ([self.iwhDelegate respondsToSelector:@selector(IWHOpenNewWindow:)]) {
            [self.iwhDelegate IWHOpenNewWindow:urlDic[@"url"]];
        }
    } else {
        [self loadRequest:urlDic[@"url"]];
        
    }
}

- (void)closeWebView:(NSString *)jsonStr {
    if (!self.isMainWebView) {
        [self removeFromSuperview];
    } else {
        if ([self.iwhDelegate respondsToSelector:@selector(IWHWebViewDidClose)]) {
            [self.iwhDelegate IWHWebViewDidClose];
        }
    }
}

- (void)getDeviceInfo {
    [self p_ocCallJS:@"IWH.appGetSystemInfo" parameter:@{@"c":@"1", @"deviceName":@"ios", @"sysVer":[NSString stringWithFormat:@"%f", self.sysVer]}];
}

- (void)getAppInfo {
    [self p_ocCallJS:@"IWH.appGetAppInfo" parameter:@{@"c":@"1", @"appVer":[ILGLocalData preferencePlistObject:@"CFBundleShortVersionString"]}];
}

- (void)getToken {
    
//    [self p_ocCallJS:@"IWH.appGetToken" parameter:@{@"c":@"1", @"token":[IWHLoginManager token]}];
}

- (void)messageSomeone:(NSString *)jsonStr {
    NSDictionary *dict = [ILGEncrypt dictionaryWithJsonString:jsonStr];
    if ([self.iwhDelegate respondsToSelector:@selector(IWHMessageSomeone:)]) {
        [self.iwhDelegate IWHMessageSomeone:dict];
    }
}


#pragma mark - Event

- (IBAction)leftBtnClick:(id)sender {
    if (!self.isMainWebView) {
        [self removeFromSuperview];
    } else {
        if ([self.iwhDelegate respondsToSelector:@selector(IWHWebViewDidClose)]) {
            [self.iwhDelegate IWHWebViewDidClose];
        }
    }
}

- (IBAction)rightBtnClick:(id)sender {
}


#pragma mark - other
- (void)p_ocCallJS:(NSString *)methodName parameter:(NSDictionary *)dic {
    NSString *jsString = [NSString stringWithFormat:@"%@('%@')", methodName, [ILGEncrypt getJsonString:dic]];
    NSLog(@"p_ocCallJS jsString:%@", jsString);
    if (self.sysVer >= 8.0) {
        [(WKWebView *)self.webView evaluateJavaScript:jsString completionHandler:^(id _Nullable object, NSError * _Nullable error) {
            
        }];
    } else {
        [(UIWebView *)self.webView stringByEvaluatingJavaScriptFromString:[ILGEncrypt getJsonString:dic]];
    }
}

- (void)p_addScriptMessageHandlers {
    WeakScriptMessageDelegate *weakDelegate = [[WeakScriptMessageDelegate alloc] initWithDelegate:self];
    WKWebView *webView = (WKWebView *)self.webView;
    
    for (NSString *name in self.jsMethodHandleArr) {
        [webView.configuration.userContentController addScriptMessageHandler:weakDelegate name:name];
    }
}

- (void)p_removeScriptMessageHandlers {
    WKWebView *webView = (WKWebView *)self.webView;
    for (NSString *name in self.jsMethodHandleArr) {
        [webView.configuration.userContentController removeScriptMessageHandlerForName:name];
    }
}

- (void)p_setDelegate {
    self.jsContent = [self.webView valueForKeyPath:@"documentView.webView.mainFrame.javaScriptContext"];
    self.jsContent[@"YYGInterface"] = self;
    self.jsContent.exceptionHandler = ^(JSContext *context, JSValue *exception) {
        context.exception = exception;
        NSLog(@"异常信息：%@", exception);
    };
}

@end

/* 使用说明
 1.UIWebView:需要在JSObjectDelegate中声明对应方法
 2.WKWebView:需要修改p_addScriptMessageHandlers中注册的方法名
 */
